package br.com.hs.nfe.common.to;

import br.com.hs.nfe.common.anotation.Element;
import br.com.hs.nfe.common.anotation.TypeEnum;
import br.com.hs.nfe.common.enumeration.CSOSNEnum;
import br.com.hs.nfe.common.enumeration.CSTEnum;
import br.com.hs.nfe.common.enumeration.ModBCEnum;
import br.com.hs.nfe.common.enumeration.ModBCSTEnum;
import br.com.hs.nfe.common.enumeration.MotDesICMSEnum;
import br.com.hs.nfe.common.enumeration.OrigEnum;
import br.com.hs.nfe.common.enumeration.UFEnum;
import br.inf.portalfiscal.nfe.TNFe.InfNFe.Det.Imposto.ICMS;
import br.inf.portalfiscal.nfe.TUf;
import br.inf.portalfiscal.nfe.Torig;
import java.math.BigDecimal;

/**
 * Classe de informações do ICMS da operação própria e ST.
 * @author Ranlive Hrysyk
 */
public class IcmsTO extends BaseTO {

    @Element(publicName = "Origem da Mercadoria", type = TypeEnum.ENUM, classType = Torig.Enum.class)
    private OrigEnum orig;
    @Element(elementName = "CST", publicName = "Cód. Situação Tributária do ICMS", type = TypeEnum.ENUM, classType = {ICMS.ICMS00.CST.Enum.class, ICMS.ICMS10.CST.Enum.class, ICMS.ICMS20.CST.Enum.class, ICMS.ICMS30.CST.Enum.class, ICMS.ICMS40.CST.Enum.class, ICMS.ICMS51.CST.Enum.class, ICMS.ICMS60.CST.class, ICMS.ICMS70.CST.Enum.class, ICMS.ICMS90.CST.Enum.class, ICMS.ICMSPart.CST.Enum.class, ICMS.ICMSST.CST.Enum.class})
    private CSTEnum cst;
    @Element(elementName = "CSOSN", publicName = "Cód. de Situação da Operação do ICMS", type = TypeEnum.ENUM, classType = {ICMS.ICMSSN101.CSOSN.Enum.class, ICMS.ICMSSN102.CSOSN.Enum.class, ICMS.ICMSSN201.CSOSN.Enum.class, ICMS.ICMSSN202.CSOSN.Enum.class, ICMS.ICMSSN500.CSOSN.Enum.class, ICMS.ICMSSN900.CSOSN.Enum.class}, required = false)
    private CSOSNEnum csosn;
    @Element(publicName = "Modalidade da BC do ICMS", type = TypeEnum.ENUM, classType = {ICMS.ICMS00.ModBC.Enum.class, ICMS.ICMS10.ModBC.Enum.class, ICMS.ICMS20.ModBC.Enum.class, ICMS.ICMS51.ModBC.Enum.class, ICMS.ICMS70.ModBC.Enum.class, ICMS.ICMS90.ModBC.Enum.class, ICMS.ICMSPart.ModBC.Enum.class, ICMS.ICMSSN900.ModBC.Enum.class}, required = false)
    private ModBCEnum modBC;
    @Element(publicName = "Modalidade da BC do ICMS ST", type = TypeEnum.ENUM, classType = {ICMS.ICMS10.ModBCST.Enum.class, ICMS.ICMS30.ModBCST.Enum.class, ICMS.ICMS70.ModBCST.Enum.class, ICMS.ICMS90.ModBCST.Enum.class, ICMS.ICMSPart.ModBCST.Enum.class, ICMS.ICMSSN201.ModBCST.Enum.class, ICMS.ICMSSN202.ModBCST.Enum.class, ICMS.ICMSSN900.ModBCST.Enum.class}, required = false)
    private ModBCSTEnum modBCST;
    @Element(publicName = "Valor da BC do ICMS", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal vBC;
    @Element(publicName = "Valor da BC do ICMS ST", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal vBCST;
    @Element(publicName = "Valor da BC do ICMS  Retido", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal vBCSTRet;
    @Element(publicName = "Valor da BC do ICMS da UF destino", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal vBCSTDest;
    @Element(publicName = "Alíq. do Imposto", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal pICMS;
    @Element(publicName = "Alíq. do Imposto do ICMS ST", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal pICMSST;
    @Element(publicName = "Valor do IMCS", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal vICMS;
    @Element(publicName = "Valor do IMCS ST", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal vICMSST;
    @Element(publicName = "Valor do IMCS ST Retido", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal vICMSSTRet;
    @Element(publicName = "Valor do IMCS ST da UF destino", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal vICMSSTDest;
    @Element(publicName = "Perc. da Margem de Valor Adicionado ICMS ST", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal pMVAST;
    @Element(publicName = "Perc. da Redução de BC", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal pRedBC;
    @Element(publicName = "Perc. da Redução de BC do ICMS ST", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal pRedBCST;
    @Element(publicName = "Motivo da Desoneração do ICMS", type = TypeEnum.ENUM, classType = ICMS.ICMS40.MotDesICMS.Enum.class, required = false)
    private MotDesICMSEnum motDesICMS;
    @Element(publicName = "Perc. da BC Operação Própria", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal pBCOp;
    @Element(elementName = "UFST", publicName = "UF do ICMS ST", type = TypeEnum.ENUM, classType = TUf.Enum.class, required = false)
    private UFEnum ufST;
    @Element(publicName = "Alíq. Cálculo do Crédito", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal pCredSN;
    @Element(publicName = "Valor Crédito do ICMS", type = TypeEnum.DECIMAL, decimalCount = 2, required = false)
    private BigDecimal vCredICMSSN;

    /**
     * Origem da Mercadoria.
     */
    public OrigEnum getOrigEnum() {
        return orig;
    }

    /**
     * Origem da Mercadoria.
     */
    public String getOrig() {
        if (orig != null) {
            return orig.getCodigo();
        }
        return null;
    }

    /**
     * Informar a origem da mercadoria.
     * @param orig Origem da Mercadoria
     */
    public void setOrigEnum(OrigEnum orig) {
        this.orig = orig;
    }

    /**
     * Informar a origem da mercadoria.
     * <p>Este campo deverá ser obrigatoriamente preenchido com:
     * <br>0 - Nacional;
     * <br>1 - Estrangeira - Importação direta;
     * <br>2 - Estrangeira - Adquirida no mercado interno.
     * </p>
     * @param orig Origem da Mercadoria
     */
    public void setOrig(String orig) {
        this.orig = OrigEnum.getEnumByCodigo(orig);

    }

    /**
     * Código de Tributação.
     */
    public CSTEnum getCSTEnum() {
        return cst;
    }

    /**
     * Código de Tributação.
     */
    public String getCST() {
        if (cst != null) {
            return cst.getCST();
        }
        return null;
    }

    /**
     * Informar o código de tributação.
     * @param cst Código de Tributação
     */
    public void setCSTEnum(CSTEnum cst) {
        this.cst = cst;
    }

    /**
     * Informar o código de tributação.
     * <p>Este campo deverá ser preenchido com:
     * <br>00 - Tributada integralmente;
     * <br>10 - Tributada com cobrança do ICMS por ST;
     * <br>20 - Com redução da base de cálculo;
     * <br>30 - Isenta ou não tributada e com cobrança do ICMS por ST;
     * <br>40 - Isenta;
     * <br>41 - Não tributada;
     * <br>50 - Suspensão;
     * <br>51 - Diferimento;
     * <br>60 - Cobrado anteriormente por ST;
     * <br>70 - Com redução da base de cálculo e cobrança do ICMS por ST;
     * <br>90 - Outras;
     * <br>10 - Tributada com cobrança do ICMS por ST (com partilha do ICMS entre a UF de origem e a UF de destino ou a UF definida na legislação);
     * <br>90 - Outras (com partilha do ICMS entre a UF de origem e a UF de destino ou a UF definida na legislação);
     * <br>41 - Não tributada (ICMSST devido para a UF de destino, nas operações interestaduais de produtos que tiveram retenção antecipada de ICMS por ST na UF do rementente).
     * </p>
     * @param cst Código de Tributação
     */
    public void setCST(String cst) {
        this.cst = CSTEnum.getEnumByCodigo(cst);
    }

    /**
     * Código de Situação da Operação.
     */
    public CSOSNEnum getCSOSNEnum() {
        return csosn;
    }

    /**
     * Código de Situação da Operação.
     */
    public String getCSOSN() {
        if (csosn != null) {
            return csosn.getCSOSN();
        }
        return null;
    }

    /**
     * Informar o código de situação da operação.
     * @param csosn Código de Situação da Operação
     */
    public void setCSOSNEnum(CSOSNEnum csosn) {
        this.csosn = csosn;
    }

    /**
     * Informar o código de situação da operação.
     * <p>Este campo deverá ser preenchido com:
     * <br>101 - Tributada com permissão de crédito;
     * <br>102 - Tributada sem permissão de crédito;
     * <br>103 - Isenção do ICMS para faixa de receita bruta;
     * <br>201 - Tributada com permissão de crédito e com cobrança do ICMS por ST;
     * <br>202 - Tributada sem permissão de crédito e com cobrança do ICMS por ST;
     * <br>203 - Isenção do ICMS para faixa de receita bruta e com cobrança do ICMS por ST;
     * <br>300 - Imune;
     * <br>400 - Não tributada;
     * <br>500 - ICMS cobrado anteriormente por ST ou por antecipação;
     * <br>900 - Outros.
     * </p>
     * @param csosn Código de Situação da Operação
     */
    public void setCSOSN(String csosn) {
        this.csosn = CSOSNEnum.getEnumByCodigo(csosn);
    }

    /**
     * Modalidade da BC do ICMS.
     */
    public ModBCEnum getModBCEnum() {
        return modBC;
    }

    /**
     * Modalidade da BC do ICMS.
     */
    public String getModBC() {
        if (modBC != null) {
            return modBC.getCodigo();
        }
        return null;
    }

    /**
     * Informar a modalidade de determinação da BC do ICMS.
     * @param modBC Modalidade da BC do ICMS
     */
    public void setModBCEnum(ModBCEnum modBC) {
        this.modBC = modBC;
    }

    /**
     * Informar a modalidade de determinação da BC do ICMS.
     * <p>Este campo deverá ser preenchido com:
     * <br>0 - Margem Valor Agregado;
     * <br>1 - Pauta (valor);
     * <br>2 - Preço Tabelado Máx. (valor);
     * <br>3 - Valor da Operação.
     * </p>
     * @param modBC Modalidade da BC do ICMS
     */
    public void setModBC(String modBC) {
        this.modBC = ModBCEnum.getEnumByCodigo(modBC);
    }

    /**
     * Modalidade da BC do ICMS ST.
     */
    public ModBCSTEnum getModBCSTEnum() {
        return modBCST;
    }

    /**
     * Modalidade da BC do ICMS ST.
     */
    public String getModBCST() {
        if (modBCST != null) {
            return modBCST.getCodigo();
        }
        return null;
    }

    /**
     * Informar a modalidade de determinação da BC do ICMS ST.
     * @param modBCST Modalidade da BC do ICMS
     */
    public void setModBCSTEnum(ModBCSTEnum modBCST) {
        this.modBCST = modBCST;
    }

    /**
     * Informar a modalidade de determinação da BC do ICMS ST.
     * <p>Este campo deverá ser preenchido com:
     * <br>0 - Preço Tabelado ou Máximo Sugerido;
     * <br>1 - Lista Negativa (valor);
     * <br>2 - Lista Positiva (valor);
     * <br>3 - Lista Neutra (valor);
     * <br>4 - Margem Valor Agregado (%);
     * <br>5 - Pauta (valor);
     * </p>
     * @param modBCST Modalidade da BC do ICMS
     */
    public void setModBCST(String modBCST) {
        this.modBCST = ModBCSTEnum.getEnumByCodigo(modBCST);
    }

    /**
     * Valor da BC do ICMS.
     */
    public BigDecimal getVBC() {
        return vBC;
    }

    /**
     * Informar o valor da base de cálculo do ICMS.
     * @param vBC Valor da BC do ICMS
     */
    public void setVBC(BigDecimal vBC) {
        this.vBC = vBC;
    }

    /**
     * Valor da BC do ICMS ST.
     */
    public BigDecimal getVBCST() {
        return vBCST;
    }

    /**
     * Informar o valor da base de cálculo do ICMS ST.
     * @param vBCST Valor da BC do ICMS ST
     */
    public void setVBCST(BigDecimal vBCST) {
        this.vBCST = vBCST;
    }

    /**
     * Valor da BC do ICMS ST Retido.
     */
    public BigDecimal getVBCSTRet() {
        return vBCSTRet;
    }

    /**
     * Informar o valor da base de cálculo do ICMS ST retido.
     * @param vBCST Valor da BC do ICMS ST Retido
     */
    public void setVBCSTRet(BigDecimal vBCSTRet) {
        this.vBCSTRet = vBCSTRet;
    }

    /**
     * Valor da BC do ICMS ST da UF destino.
     */
    public BigDecimal getVBCSTDest() {
        return vBCSTDest;
    }

    /**
     * Informar o valor da base de cálculo do ICMS ST da UF destino.
     * @param vBCSTDest Valor da BC do ICMS ST da UF destino
     */
    public void setVBCSTDest(BigDecimal vBCSTDest) {
        this.vBCSTDest = vBCSTDest;
    }

    /**
     * Alíquota do Imposto.
     */
    public BigDecimal getPICMS() {
        return pICMS;
    }

    /**
     * Informar o percentual de alíquota do imposto.
     * @param pICMS Alíquota do Imposto.
     */
    public void setPICMS(BigDecimal pICMS) {
        this.pICMS = pICMS;
    }

    /**
     * Alíquota do Imposto do ICMS ST.
     */
    public BigDecimal getPICMSST() {
        return pICMSST;
    }

    /**
     * Informar o percentual de alíquota do imposto do ICMS ST.
     * @param pICMSST Alíquota do Imposto do ICMS ST.
     */
    public void setPICMSST(BigDecimal pICMSST) {
        this.pICMSST = pICMSST;
    }

    /**
     * Valor do ICMS.
     */
    public BigDecimal getVICMS() {
        return vICMS;
    }

    /**
     * Informar o valor do ICMS.
     * @param vICMS Valor do ICMS
     */
    public void setVICMS(BigDecimal vICMS) {
        this.vICMS = vICMS;
    }

    /**
     * Valor do ICMS ST.
     */
    public BigDecimal getVICMSST() {
        return vICMSST;
    }

    /**
     * Informar o valor do ICMS ST.
     * @param vICMSST Valor do ICMS ST
     */
    public void setVICMSST(BigDecimal vICMSST) {
        this.vICMSST = vICMSST;
    }

    /**
     * Valor do ICMS ST Retido.
     */
    public BigDecimal getVICMSSTRet() {
        return vICMSSTRet;
    }

    /**
     * Informar o valor do ICMS ST retido.
     * @param vICMSST Valor do ICMS ST Retido
     */
    public void setVICMSSTRet(BigDecimal vICMSSTRet) {
        this.vICMSSTRet = vICMSSTRet;
    }

    /**
     * Valor do ICMS ST da UF destino.
     */
    public BigDecimal getVICMSSTDest() {
        return vICMSSTDest;
    }

    /**
     * Informar o valor do ICMS ST da UF destino.
     * @param vICMSSTDest Valor do ICMS ST da UF destino
     */
    public void setVICMSSTDest(BigDecimal vICMSSTDest) {
        this.vICMSSTDest = vICMSSTDest;
    }

    /**
     * Percentual da margem de valor adicionado do ICMS ST.
     */
    public BigDecimal getPMVAST() {
        return pMVAST;
    }

    /**
     * Informar o percentual da margem de valor adicionado do ICMS ST.
     * @param pMVAST Percentual da margem de valor adicionado do ICMS ST
     */
    public void setPMVAST(BigDecimal pMVAST) {
        this.pMVAST = pMVAST;
    }

    /**
     * Percentual da redução de BC do ICMS.
     */
    public BigDecimal getPRedBC() {
        return pRedBC;
    }

    /**
     * Informar o percentual da redução de BC do ICMS.
     * @param pRedBC Percentual da redução de BC do ICMS
     */
    public void setPRedBC(BigDecimal pRedBC) {
        this.pRedBC = pRedBC;
    }

    /**
     * Percentual da redução de BC do ICMS ST.
     */
    public BigDecimal getPRedBCST() {
        return pRedBCST;
    }

    /**
     * Informar o percentual da redução de BC do ICMS ST.
     * @param pRedBCST Percentual da redução de BC do ICMS ST
     */
    public void setPRedBCST(BigDecimal pRedBCST) {
        this.pRedBCST = pRedBCST;
    }

    /**
     * Motivo da desoneração do ICMS.
     */
    public MotDesICMSEnum getMotDesICMSEnum() {
        return motDesICMS;
    }

    /**
     * Motivo da desoneração do ICMS.
     */
    public String getMotDesICMS() {
        if (motDesICMS != null) {
            return motDesICMS.getCodigo();
        }
        return null;
    }

    /**
     * Informar o motivo da desoneração do ICMS.
     * <p>Este campo deverá ser preenchido com:
     * <br>Táxi;
     * <br>Deficiente Físico;
     * <br>Produtor Agropecuário;
     * <br>Frotista/Locadora;
     * <br>Diplomático/Consular;
     * <br>Utilitátios e Motocicletas da Amazônia Ocidental e Áreas de Livre Comércio;
     * <br>SUFRAMA;
     * <br>Outros.
     * </p>
     * @param motDesICMS Motivo da desoneração do ICMS
     */
    public void setMotDesICMS(String motDesICMS) {
        this.motDesICMS = MotDesICMSEnum.getEnumByCodigo(motDesICMS);
    }

    /**
     * Informar o motivo da desoneração do ICMS.
     * @param motDesICMS Motivo da desoneração do ICMS
     */
    public void setMotDesICMSEnum(MotDesICMSEnum motDesICMS) {
        this.motDesICMS = motDesICMS;
    }

    /**
     * Percentual da BC Operação Própria.
     */
    public BigDecimal getPBCOp() {
        return pBCOp;
    }

    /**
     * Informar a percentual da BC operação própria.
     * @param pBCOp Percentual da BC Operação Própria
     */
    public void setPBCOp(BigDecimal pBCOp) {
        this.pBCOp = pBCOp;
    }

    /**
     * UF do ICMS ST.
     */
    public UFEnum getUFSTEnum() {
        return ufST;
    }

    /**
     * UF do ICMS ST.
     */
    public String getUFST() {
        if (ufST != null) {
            return ufST.getUF();
        }
        return null;
    }

    /**
     * Informar a sigla da UF para qual é devido o ICMS ST da operação.
     * @param ufST UF do ICMS ST
     */
    public void setUFSTEnum(UFEnum ufST) {
        this.ufST = ufST;
    }

    /**
     * Informar a sigla da UF para qual é devido o ICMS ST da operação.
     * @param ufST UF do ICMS ST
     */
    public void setUFST(String ufST) {
        this.ufST = UFEnum.getEnumByUF(ufST);
    }

    /**
     * Alíquota do Cálculo do Crédito.
     */
    public BigDecimal getPCredSN() {
        return pCredSN;
    }

    /**
     * Informar a alíquota aplicável de cálculo do crédito (Simples Nacional).
     * @param pCredSN Alíquota do Cálculo do Crédito
     */
    public void setPCredSN(BigDecimal pCredSN) {
        this.pCredSN = pCredSN;
    }

    /**
     * Valor Crédito do ICMS.
     */
    public BigDecimal getVCredICMSSN() {
        return vCredICMSSN;
    }

    /**
     * Informar o valor do crédito do ICMS que pode ser aproveitado nos termos do art. 23 da LC 123 (Simples Nacional).
     * @param vCredICMSSN Valor Crédito do ICMS
     */
    public void setVCredICMSSN(BigDecimal vCredICMSSN) {
        this.vCredICMSSN = vCredICMSSN;
    }
}
